mirror of
https://github.com/darkrenaissance/darkfi.git
synced 2026-01-07 22:04:03 -05:00
validator/xmr: Add aux chain checks
This commit is contained in:
102
Cargo.lock
generated
102
Cargo.lock
generated
@@ -907,6 +907,12 @@ version = "1.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "64fa3c856b712db6612c019f14756e64e4bcea13337a6b33b696333a9eaa2d06"
|
||||
|
||||
[[package]]
|
||||
name = "byte-slice-cast"
|
||||
version = "1.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7575182f7272186991736b70173b0ea045398f984bf5ebbb3804736ce1330c9d"
|
||||
|
||||
[[package]]
|
||||
name = "bytecheck"
|
||||
version = "0.6.12"
|
||||
@@ -1257,6 +1263,26 @@ version = "0.9.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8"
|
||||
|
||||
[[package]]
|
||||
name = "const_format"
|
||||
version = "0.2.34"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "126f97965c8ad46d6d9163268ff28432e8f6a1196a55578867832e3049df63dd"
|
||||
dependencies = [
|
||||
"const_format_proc_macros",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "const_format_proc_macros"
|
||||
version = "0.2.34"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1d57c2eccfb16dbac1f4e61e206105db5820c9d26c3c472bc17c774259ef7744"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-xid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "constant_time_eq"
|
||||
version = "0.3.1"
|
||||
@@ -1798,6 +1824,7 @@ dependencies = [
|
||||
"pin-project-lite",
|
||||
"plotters",
|
||||
"prettytable-rs",
|
||||
"primitive-types",
|
||||
"rand 0.8.5",
|
||||
"randomx",
|
||||
"rcgen",
|
||||
@@ -1805,6 +1832,8 @@ dependencies = [
|
||||
"rustls-pemfile",
|
||||
"semver",
|
||||
"serde",
|
||||
"sha2",
|
||||
"simplelog",
|
||||
"sled-overlay",
|
||||
"smol",
|
||||
"socket2",
|
||||
@@ -3420,7 +3449,7 @@ dependencies = [
|
||||
"rand 0.8.5",
|
||||
"sinsemilla",
|
||||
"subtle",
|
||||
"uint",
|
||||
"uint 0.9.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -3772,6 +3801,26 @@ dependencies = [
|
||||
"png",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "impl-codec"
|
||||
version = "0.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2d40b9d5e17727407e55028eafc22b2dc68781786e6d7eb8a21103f5058e3a14"
|
||||
dependencies = [
|
||||
"parity-scale-codec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "impl-trait-for-tuples"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a0eb5a3343abf848c0984fe4604b2b105da9539376e24fc0a3b0007411ae4fd9"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.101",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "incrementalmerkletree"
|
||||
version = "0.8.2"
|
||||
@@ -4780,6 +4829,34 @@ dependencies = [
|
||||
"sha2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "parity-scale-codec"
|
||||
version = "3.7.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "799781ae679d79a948e13d4824a40970bfa500058d245760dd857301059810fa"
|
||||
dependencies = [
|
||||
"arrayvec",
|
||||
"bitvec",
|
||||
"byte-slice-cast",
|
||||
"const_format",
|
||||
"impl-trait-for-tuples",
|
||||
"parity-scale-codec-derive",
|
||||
"rustversion",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "parity-scale-codec-derive"
|
||||
version = "3.7.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "34b4653168b563151153c9e4c08ebed57fb8262bebfa79711552fa983c623e7a"
|
||||
dependencies = [
|
||||
"proc-macro-crate",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.101",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "parking"
|
||||
version = "2.2.1"
|
||||
@@ -5173,6 +5250,17 @@ dependencies = [
|
||||
"elliptic-curve",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "primitive-types"
|
||||
version = "0.13.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d15600a7d856470b7d278b3fe0e311fe28c2526348549f8ef2ff7db3299c87f5"
|
||||
dependencies = [
|
||||
"fixed-hash",
|
||||
"impl-codec",
|
||||
"uint 0.10.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "priority-queue"
|
||||
version = "2.5.0"
|
||||
@@ -8154,6 +8242,18 @@ dependencies = [
|
||||
"static_assertions",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "uint"
|
||||
version = "0.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "909988d098b2f738727b161a106cfc7cab00c539c2687a8836f8e565976fb53e"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
"crunchy",
|
||||
"hex",
|
||||
"static_assertions",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unarray"
|
||||
version = "0.1.4"
|
||||
|
||||
@@ -88,6 +88,7 @@ hex = {version = "0.4.3", optional = true}
|
||||
serde = {version = "1.0.219", features = ["derive"], optional = true}
|
||||
tinyjson = {version = "2.5.1", optional = true}
|
||||
httparse = {version = "1.10.1", optional = true}
|
||||
primitive-types = {version = "0.13.1", optional = true}
|
||||
semver = {version = "1.0.26", optional = true}
|
||||
structopt = {version= "0.3.26", optional = true}
|
||||
structopt-toml = {version= "0.5.1", optional = true}
|
||||
@@ -118,6 +119,7 @@ blake3 = {version = "1.8.2", features = ["rayon"], optional = true}
|
||||
crypto_api_chachapoly = {version = "0.5.0", optional = true}
|
||||
halo2_proofs = {version = "0.3.1", features = ["circuit-params"], optional = true}
|
||||
halo2_gadgets = {version = "0.3.1", features = ["circuit-params"], optional = true}
|
||||
sha2 = {version = "0.10.9", optional = true}
|
||||
|
||||
# Smart contract runtime
|
||||
darkfi-sdk = {path = "src/sdk", optional = true}
|
||||
@@ -172,8 +174,10 @@ validator = [
|
||||
"hex",
|
||||
"lazy_static",
|
||||
"monero",
|
||||
"primitive-types",
|
||||
"randomx",
|
||||
"smol",
|
||||
"sha2",
|
||||
|
||||
"blockchain",
|
||||
"system",
|
||||
|
||||
@@ -19,9 +19,18 @@
|
||||
|
||||
use std::{io, iter};
|
||||
|
||||
use monero::{consensus::Encodable as XmrEncodable, cryptonote::hash::Hashable, VarInt};
|
||||
use log::warn;
|
||||
use monero::{
|
||||
blockdata::transaction::{ExtraField, RawExtraField, SubField},
|
||||
consensus::Encodable as XmrEncodable,
|
||||
cryptonote::hash::Hashable,
|
||||
VarInt,
|
||||
};
|
||||
use primitive_types::U256;
|
||||
use sha2::{Digest, Sha256};
|
||||
use tiny_keccak::{Hasher, Keccak};
|
||||
|
||||
use super::merkle_tree_parameters::MerkleTreeParameters;
|
||||
use crate::{
|
||||
blockchain::{
|
||||
header_store::HeaderHash,
|
||||
@@ -31,6 +40,7 @@ use crate::{
|
||||
MoneroPowData,
|
||||
},
|
||||
},
|
||||
Error,
|
||||
Error::MoneroMergeMineError,
|
||||
Result,
|
||||
};
|
||||
@@ -136,3 +146,94 @@ pub fn construct_monero_data(
|
||||
aux_chain_merkle_proof,
|
||||
})
|
||||
}
|
||||
|
||||
fn check_aux_chains(
|
||||
monero_data: &MoneroPowData,
|
||||
merge_mining_params: VarInt,
|
||||
aux_chain_merkle_root: &monero::Hash,
|
||||
darkfi_hash: HeaderHash,
|
||||
darkfi_genesis_hash: HeaderHash,
|
||||
) -> bool {
|
||||
let df_hash = monero::Hash::from_slice(darkfi_hash.as_slice());
|
||||
|
||||
if merge_mining_params == VarInt(0) {
|
||||
// Interpret 0 as only 1 chain
|
||||
if df_hash == *aux_chain_merkle_root {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
let merkle_tree_params = MerkleTreeParameters::from_varint(merge_mining_params);
|
||||
if merkle_tree_params.number_of_chains() == 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
let hash_position = U256::from_little_endian(
|
||||
&Sha256::new()
|
||||
.chain_update(darkfi_genesis_hash.as_slice())
|
||||
.chain_update(merkle_tree_params.aux_nonce().to_le_bytes())
|
||||
.chain_update((109_u8).to_le_bytes())
|
||||
.finalize(),
|
||||
)
|
||||
.low_u32() %
|
||||
u32::from(merkle_tree_params.number_of_chains());
|
||||
|
||||
let (merkle_root, pos) = monero_data
|
||||
.aux_chain_merkle_proof
|
||||
.calculate_root_with_pos(&df_hash, merkle_tree_params.number_of_chains());
|
||||
|
||||
if hash_position != pos {
|
||||
return false
|
||||
}
|
||||
|
||||
merkle_root == *aux_chain_merkle_root
|
||||
}
|
||||
|
||||
// Parsing an extra field from bytes will always return an extra field with sub-fields
|
||||
// that could be read, even if it does not represent the original extra field. As per
|
||||
// Monero consensus rules, an error here will not represent a failure to deserialize a
|
||||
// block, so no need to error here.
|
||||
fn parse_extra_field_truncate_on_error(raw_extra_field: &RawExtraField) -> ExtraField {
|
||||
match ExtraField::try_parse(raw_extra_field) {
|
||||
Ok(val) => val,
|
||||
Err(val) => {
|
||||
warn!(
|
||||
target: "validator::xmr::helpers",
|
||||
"[MERGEMINING] Some sub-fields could not be parsed from the Monero coinbase",
|
||||
);
|
||||
val
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Extracts the Monero block hash from the coinbase transaction's extra field
|
||||
pub fn extract_aux_merkle_root_from_block(monero: &monero::Block) -> Result<Option<monero::Hash>> {
|
||||
// When we extract the merge mining hash, we do not care if
|
||||
// the extra field can be parsed without error.
|
||||
let extra_field = parse_extra_field_truncate_on_error(&monero.miner_tx.prefix.extra);
|
||||
|
||||
// Only one merge mining tag is allowed
|
||||
let merge_mining_hashes: Vec<monero::Hash> = extra_field
|
||||
.0
|
||||
.iter()
|
||||
.filter_map(|item| {
|
||||
if let SubField::MergeMining(_depth, merge_mining_hash) = item {
|
||||
Some(*merge_mining_hash)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
|
||||
if merge_mining_hashes.len() > 1 {
|
||||
return Err(Error::MoneroMergeMineError(
|
||||
"More than one merge mining tag found in coinbase".to_string(),
|
||||
))
|
||||
}
|
||||
|
||||
if let Some(merge_mining_hash) = merge_mining_hashes.into_iter().next() {
|
||||
Ok(Some(merge_mining_hash))
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user