add genesis data for all networks

This commit is contained in:
hinto.janai 2024-09-20 17:30:36 -04:00
parent 93ddbd6c5c
commit 4f87767063
No known key found for this signature in database
GPG key ID: D47CE05FA175A499
5 changed files with 164 additions and 86 deletions

2
Cargo.lock generated
View file

@ -604,7 +604,9 @@ name = "cuprate-constants"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"hex", "hex",
"hex-literal",
"monero-serai", "monero-serai",
"paste",
"pretty_assertions", "pretty_assertions",
] ]

View file

@ -14,6 +14,8 @@ monero-serai = ["dep:monero-serai"]
[dependencies] [dependencies]
monero-serai = { workspace = true, optional = true } monero-serai = { workspace = true, optional = true }
hex-literal = { workspace = true }
paste = { workspace = true }
[dev-dependencies] [dev-dependencies]
monero-serai = { workspace = true } monero-serai = { workspace = true }

View file

@ -1,6 +1,6 @@
# 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 [`crate::block::MAX_BLOCK_HEIGHT`].
## Static data ## Static data
This crate also contains `static` data used in multiple places such as the [`GENESIS_BLOCK`]. This crate also contains `static` data used in multiple places such as the [`crate::genesis::mainnet::GENESIS_BLOCK`].

View file

@ -2,106 +2,180 @@
#![expect(const_item_mutation, reason = "&mut is needed for `Read`")] #![expect(const_item_mutation, reason = "&mut is needed for `Read`")]
#[cfg(feature = "monero-serai")] /// Generate genesis block/transaction data and tests for multiple networks.
use monero_serai::{block::Block, transaction::Transaction}; ///
#[cfg(feature = "monero-serai")] /// Input string literals are in hexadecimal form.
use std::sync::LazyLock; 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>] {
#[cfg(feature = "monero-serai")]
use monero_serai::{block::Block, transaction::Transaction};
#[cfg(feature = "monero-serai")]
use std::sync::LazyLock;
/// The genesis block in [`Block`] form. #[doc = concat!("The ", stringify!([<$network:lower>]), " genesis block in [`Block`] form.")]
#[cfg(feature = "monero-serai")] #[cfg(feature = "monero-serai")]
pub static GENESIS_BLOCK: LazyLock<Block> = pub static GENESIS_BLOCK: LazyLock<Block> =
LazyLock::new(|| Block::read(&mut GENESIS_BLOCK_BYTES).unwrap()); LazyLock::new(|| Block::read(&mut GENESIS_BLOCK_BYTES).unwrap());
/// The genesis block in hexadecimal form. #[doc = concat!("The ", stringify!([<$network:lower>]), " genesis block in hexadecimal form.")]
pub const GENESIS_BLOCK_HEX: &str = "010000000000000000000000000000000000000000000000000000000000000000000010270000013c01ff0001ffffffffffff03029b2e4c0281c0b02e7c53291a94d1d0cbff8883f8024f5142ee494ffbbd08807121017767aafcde9be00dcfd098715ebcf7f410daebc582fda69d24a28e9d0bc890d100"; pub const GENESIS_BLOCK_HEX: &str = $block;
/// The genesis block in byte form. #[doc = concat!("The ", stringify!([<$network:lower>]), " genesis block in byte form.")]
pub const GENESIS_BLOCK_BYTES: &[u8] = &[ pub const GENESIS_BLOCK_BYTES: &[u8] = &hex_literal::hex!($block);
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 16, 39, 0, 0, 1, 60, 1, 255, 0, 1, 255, 255, 255, 255, 255, 255, 3, 2, 155, 46, 76, 2,
129, 192, 176, 46, 124, 83, 41, 26, 148, 209, 208, 203, 255, 136, 131, 248, 2, 79, 81, 66, 238,
73, 79, 251, 189, 8, 128, 113, 33, 1, 119, 103, 170, 252, 222, 155, 224, 13, 207, 208, 152,
113, 94, 188, 247, 244, 16, 218, 235, 197, 130, 253, 166, 157, 36, 162, 142, 157, 11, 200, 144,
209, 0,
];
/// The hash of the genesis block in hexadecimal form. #[doc = concat!("The hash of the ", stringify!([<$network:lower>]), " genesis block in hexadecimal form.")]
pub const GENESIS_BLOCK_HASH_HEX: &str = pub const GENESIS_BLOCK_HASH_HEX: &str = $block_hash;
"418015bb9ae982a1975da7d79277c2705727a56894ba0fb246adaabb1f4632e3";
/// The hash of the genesis block in byte form. #[doc = concat!("The hash of the ", stringify!([<$network:lower>]), " genesis block in byte form.")]
pub const GENESIS_BLOCK_HASH_BYTES: [u8; 32] = [ pub const GENESIS_BLOCK_HASH_BYTES: [u8; 32] = hex_literal::hex!($block_hash);
65, 128, 21, 187, 154, 233, 130, 161, 151, 93, 167, 215, 146, 119, 194, 112, 87, 39, 165, 104,
148, 186, 15, 178, 70, 173, 170, 187, 31, 70, 50, 227,
];
/// The genesis block in [`Transaction`] form. #[doc = concat!("The ", stringify!([<$network:lower>]), " genesis block in [`Transaction`] form.")]
#[cfg(feature = "monero-serai")] #[cfg(feature = "monero-serai")]
pub static GENESIS_TX: LazyLock<Transaction> = pub static GENESIS_TX: LazyLock<Transaction> =
LazyLock::new(|| Transaction::read(&mut GENESIS_TX_BYTES).unwrap()); LazyLock::new(|| Transaction::read(&mut GENESIS_TX_BYTES).unwrap());
/// The genesis transaction in hexadecimal form. #[doc = concat!("The ", stringify!([<$network:lower>]), " genesis transaction in hexadecimal form.")]
pub const GENESIS_TX_HEX: &str = "013c01ff0001ffffffffffff03029b2e4c0281c0b02e7c53291a94d1d0cbff8883f8024f5142ee494ffbbd08807121017767aafcde9be00dcfd098715ebcf7f410daebc582fda69d24a28e9d0bc890d1"; pub const GENESIS_TX_HEX: &str = $tx;
/// The genesis transaction in byte form. #[doc = concat!("The ", stringify!([<$network:lower>]), " genesis transaction in byte form.")]
pub const GENESIS_TX_BYTES: &[u8] = &[ pub const GENESIS_TX_BYTES: &[u8] = &hex_literal::hex!($tx);
1, 60, 1, 255, 0, 1, 255, 255, 255, 255, 255, 255, 3, 2, 155, 46, 76, 2, 129, 192, 176, 46,
124, 83, 41, 26, 148, 209, 208, 203, 255, 136, 131, 248, 2, 79, 81, 66, 238, 73, 79, 251, 189,
8, 128, 113, 33, 1, 119, 103, 170, 252, 222, 155, 224, 13, 207, 208, 152, 113, 94, 188, 247,
244, 16, 218, 235, 197, 130, 253, 166, 157, 36, 162, 142, 157, 11, 200, 144, 209,
];
/// The hash of the genesis transaction in hexadecimal form. #[doc = concat!("The hash of the ", stringify!([<$network:lower>]), " genesis transaction in hexadecimal form.")]
pub const GENESIS_TX_HASH_HEX: &str = pub const GENESIS_TX_HASH_HEX: &str = $tx_hash;
"c88ce9783b4f11190d7b9c17a69c1c52200f9faaee8e98dd07e6811175177139";
/// The hash of the genesis transaction in byte form. #[doc = concat!("The hash of the ", stringify!([<$network:lower>]), " genesis transaction in byte form.")]
pub const GENESIS_TX_HASH_BYTES: [u8; 32] = [ pub const GENESIS_TX_HASH_BYTES: [u8; 32] = hex_literal::hex!($tx_hash);
200, 140, 233, 120, 59, 79, 17, 25, 13, 123, 156, 23, 166, 156, 28, 82, 32, 15, 159, 170, 238,
142, 152, 221, 7, 230, 129, 17, 117, 23, 113, 57,
];
#[cfg(test)] #[doc = concat!("The nonce of the ", stringify!([<$network:lower>]), " genesis block.")]
mod test { pub const GENESIS_NONCE: u32 = $nonce;
use monero_serai::{block::Block, transaction::Transaction};
use pretty_assertions::assert_eq;
use super::*; // Generate tests for all input networks.
#[cfg(test)]
mod test {
use monero_serai::{block::Block, transaction::Transaction};
use pretty_assertions::assert_eq;
#[test] use super::*;
fn genesis_block() {
assert_eq!(hex::decode(GENESIS_BLOCK_HEX).unwrap(), GENESIS_BLOCK_BYTES);
assert_eq!(GENESIS_BLOCK_HEX, hex::encode(GENESIS_BLOCK_BYTES));
assert_eq!( #[test]
hex::decode(GENESIS_BLOCK_HASH_HEX).unwrap(), /// Assert the block bytes/hash are correct.
GENESIS_BLOCK_HASH_BYTES fn genesis_block() {
); let block = Block::read(&mut GENESIS_BLOCK_BYTES).unwrap();
assert_eq!( assert_eq!(block.serialize(), &*GENESIS_BLOCK_BYTES);
GENESIS_BLOCK_HASH_HEX, assert_eq!(block.hash(), GENESIS_BLOCK_HASH_BYTES);
hex::encode(GENESIS_BLOCK_HASH_BYTES) assert_eq!(block.hash(), GENESIS_BLOCK.hash());
); assert_eq!(&block, &*GENESIS_BLOCK);
}
let block = Block::read(&mut GENESIS_BLOCK_BYTES).unwrap(); #[test]
assert_eq!(block.hash(), GENESIS_BLOCK_HASH_BYTES); /// Assert the genesis transaction in the block is correct.
assert_eq!(block.hash(), GENESIS_BLOCK.hash()); fn genesis_block_tx() {
assert_eq!(&block, &*GENESIS_BLOCK); 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",
} }
#[test] Testnet {
fn genesis_tx() { nonce: 10001,
assert_eq!(hex::decode(GENESIS_TX_HEX).unwrap(), GENESIS_TX_BYTES); block: "010000000000000000000000000000000000000000000000000000000000000000000011270000013c01ff0001ffffffffffff03029b2e4c0281c0b02e7c53291a94d1d0cbff8883f8024f5142ee494ffbbd08807121017767aafcde9be00dcfd098715ebcf7f410daebc582fda69d24a28e9d0bc890d100",
assert_eq!(GENESIS_TX_HEX, hex::encode(GENESIS_TX_BYTES)); block_hash: "48ca7cd3c8de5b6a4d53d2861fbdaedca141553559f9be9520068053cda8430b",
tx: "013c01ff0001ffffffffffff03029b2e4c0281c0b02e7c53291a94d1d0cbff8883f8024f5142ee494ffbbd08807121017767aafcde9be00dcfd098715ebcf7f410daebc582fda69d24a28e9d0bc890d1",
tx_hash: "c88ce9783b4f11190d7b9c17a69c1c52200f9faaee8e98dd07e6811175177139",
}
assert_eq!( Stagenet {
hex::decode(GENESIS_TX_HASH_HEX).unwrap(), nonce: 10002,
GENESIS_TX_HASH_BYTES block: "010000000000000000000000000000000000000000000000000000000000000000000012270000013c01ff0001ffffffffffff0302df5d56da0c7d643ddd1ce61901c7bdc5fb1738bfe39fbe69c28a3a7032729c0f2101168d0c4ca86fb55a4cf6a36d31431be1c53a3bd7411bb24e8832410289fa6f3b00",
); block_hash: "76ee3cc98646292206cd3e86f74d88b4dcc1d937088645e9b0cbca84b7ce74eb",
assert_eq!(GENESIS_TX_HASH_HEX, hex::encode(GENESIS_TX_HASH_BYTES)); tx: "013c01ff0001ffffffffffff0302df5d56da0c7d643ddd1ce61901c7bdc5fb1738bfe39fbe69c28a3a7032729c0f2101168d0c4ca86fb55a4cf6a36d31431be1c53a3bd7411bb24e8832410289fa6f3b",
tx_hash: "c099809301da6ad2fde11969b0e9cb291fc698f8dc678cef00506e7baf561de4",
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);
} }
} }

View file

@ -1,7 +1,7 @@
//! Contains [`BlockCompleteEntry`] and the related types. //! Contains [`BlockCompleteEntry`] and the related types.
//---------------------------------------------------------------------------------------------------- Import //---------------------------------------------------------------------------------------------------- Import
#[cfg(feature = "epee")] // #[cfg(feature = "epee")]
use bytes::Bytes; use bytes::Bytes;
#[cfg(feature = "serde")] #[cfg(feature = "serde")]