mirror of
https://github.com/hinto-janai/cuprate.git
synced 2024-12-23 03:59:37 +00:00
Compare commits
3 commits
fd84940ee6
...
e975c420d9
Author | SHA1 | Date | |
---|---|---|---|
|
e975c420d9 | ||
|
1f3b5ed127 | ||
|
46bf19861a |
3 changed files with 198 additions and 31 deletions
|
@ -8,11 +8,15 @@
|
|||
use anyhow::{anyhow, Error};
|
||||
use monero_serai::block::Block;
|
||||
|
||||
use cuprate_consensus::{BlockChainContext, BlockChainContextService};
|
||||
use cuprate_helper::{cast::usize_to_u64, map::split_u128_into_low_high_bits};
|
||||
use cuprate_rpc_types::misc::{BlockHeader, KeyImageSpentStatus};
|
||||
use cuprate_types::ExtendedBlockHeader;
|
||||
|
||||
use crate::{rpc::request::blockchain, rpc::CupratedRpcHandler};
|
||||
use crate::{
|
||||
rpc::request::{blockchain, blockchain_context},
|
||||
rpc::CupratedRpcHandler,
|
||||
};
|
||||
|
||||
pub(super) fn into_block_header(
|
||||
height: u64,
|
||||
|
|
|
@ -13,7 +13,7 @@ use cuprate_constants::{
|
|||
rpc::{RESTRICTED_BLOCK_COUNT, RESTRICTED_BLOCK_HEADER_RANGE},
|
||||
};
|
||||
use cuprate_helper::{
|
||||
cast::{u64_to_usize, usize_to_u64},
|
||||
cast::{u32_to_usize, u64_to_usize, usize_to_u64},
|
||||
map::split_u128_into_low_high_bits,
|
||||
};
|
||||
use cuprate_p2p_core::{client::handshaker::builder::DummyAddressBook, ClearNet, Network};
|
||||
|
@ -403,7 +403,7 @@ async fn get_info(
|
|||
let (database_size, free_space) = blockchain::database_size(&mut state.blockchain_read).await?;
|
||||
let (database_size, free_space) = if restricted {
|
||||
// <https://github.com/monero-project/monero/blob/cc73fe71162d564ffda8e549b79a350bca53c454/src/rpc/core_rpc_server.cpp#L131-L134>
|
||||
fn round_up(value: u64, quantum: u64) -> u64 {
|
||||
const fn round_up(value: u64, quantum: u64) -> u64 {
|
||||
(value + quantum - 1) / quantum * quantum
|
||||
}
|
||||
let database_size = round_up(database_size, 5 * 1024 * 1024 * 1024);
|
||||
|
@ -931,20 +931,31 @@ async fn calc_pow(
|
|||
let block = Block::read(&mut block_blob.as_slice())?;
|
||||
let seed_hash = helper::hex_to_hash(request.seed_hash)?;
|
||||
|
||||
// let pow_hash = blockchain_manager::calculate_pow(
|
||||
// &mut state.blockchain_manager,
|
||||
// hardfork,
|
||||
// request.height,
|
||||
// block,
|
||||
// seed_hash,
|
||||
// )
|
||||
// .await?;
|
||||
let block_weight = todo!("calculate block weight");
|
||||
|
||||
// let hex = hex::encode(pow_hash);
|
||||
let median_for_block_reward = blockchain_context::context(&mut state.blockchain_context)
|
||||
.await?
|
||||
.unchecked_blockchain_context()
|
||||
.context_to_verify_block
|
||||
.median_weight_for_block_reward;
|
||||
|
||||
let hex = todo!();
|
||||
if cuprate_consensus_rules::blocks::check_block_weight(block_weight, median_for_block_reward)
|
||||
.is_err()
|
||||
{
|
||||
return Err(anyhow!("Block blob size is too big, rejecting block"));
|
||||
}
|
||||
|
||||
Ok(CalcPowResponse { pow_hash: hex })
|
||||
let pow_hash = blockchain_context::calculate_pow(
|
||||
&mut state.blockchain_context,
|
||||
hardfork,
|
||||
block,
|
||||
seed_hash,
|
||||
)
|
||||
.await?;
|
||||
|
||||
let pow_hash = hex::encode(pow_hash);
|
||||
|
||||
Ok(CalcPowResponse { pow_hash })
|
||||
}
|
||||
|
||||
/// <https://github.com/monero-project/monero/blob/cc73fe71162d564ffda8e549b79a350bca53c454/src/rpc/core_rpc_server.cpp#L3542-L3551>
|
||||
|
@ -964,8 +975,9 @@ async fn add_aux_pow(
|
|||
mut state: CupratedRpcHandler,
|
||||
request: AddAuxPowRequest,
|
||||
) -> Result<AddAuxPowResponse, Error> {
|
||||
let hex = hex::decode(request.blocktemplate_blob)?;
|
||||
let block_template = Block::read(&mut hex.as_slice())?;
|
||||
if request.aux_pow.is_empty() {
|
||||
return Err(anyhow!("Empty `aux_pow` vector"));
|
||||
}
|
||||
|
||||
let aux_pow = request
|
||||
.aux_pow
|
||||
|
@ -975,31 +987,177 @@ async fn add_aux_pow(
|
|||
let hash = helper::hex_to_hash(aux.hash)?;
|
||||
Ok(cuprate_types::AuxPow { id, hash })
|
||||
})
|
||||
.collect::<Result<Vec<_>, Error>>()?;
|
||||
.collect::<Result<Box<[_]>, Error>>()?;
|
||||
// Some of the code below requires that the
|
||||
// `.len()` of certain containers are the same.
|
||||
// Boxed slices are used over `Vec` to slightly
|
||||
// safe-guard against accidently pushing to it.
|
||||
|
||||
let resp = todo!();
|
||||
// let resp =
|
||||
// blockchain_manager::add_aux_pow(&mut state.blockchain_manager, block_template, aux_pow)
|
||||
// .await?;
|
||||
// --- BEGIN AUX POW IMPL ---
|
||||
|
||||
let blocktemplate_blob = hex::encode(resp.blocktemplate_blob);
|
||||
let blockhashing_blob = hex::encode(resp.blockhashing_blob);
|
||||
let merkle_root = hex::encode(resp.merkle_root);
|
||||
let aux_pow = resp
|
||||
.aux_pow
|
||||
.into_iter()
|
||||
// Original impl:
|
||||
// <https://github.com/monero-project/monero/blob/cc73fe71162d564ffda8e549b79a350bca53c454/src/rpc/core_rpc_server.cpp#L2110-L2206>
|
||||
|
||||
let len = aux_pow.len();
|
||||
|
||||
let mut path_domain = 1_usize;
|
||||
while 1 << path_domain < len {
|
||||
path_domain += 1;
|
||||
}
|
||||
|
||||
let mut nonce = 0_u32;
|
||||
let mut collision = true;
|
||||
let mut slots: Box<[u32]> = vec![0; len].into_boxed_slice(); // INVARIANT: this must be the same `.len()` as `aux_pow`
|
||||
|
||||
for n in 0..u32::MAX {
|
||||
nonce = n;
|
||||
|
||||
let slot_seen: Vec<bool> = vec![false; len];
|
||||
|
||||
collision = false;
|
||||
|
||||
slots.iter_mut().for_each(|i| *i = u32::MAX);
|
||||
|
||||
for i in &mut slots {
|
||||
let slot_u32: u32 = todo!("const uint32_t slot = cryptonote::get_aux_slot(aux_pow[idx].first, nonce, aux_pow.size());");
|
||||
let slot = u32_to_usize(slot_u32);
|
||||
|
||||
if slot >= len {
|
||||
return Err(anyhow!("Computed slot is out of range"));
|
||||
}
|
||||
|
||||
if slot_seen[slot] {
|
||||
collision = true;
|
||||
break;
|
||||
}
|
||||
|
||||
slot_seen[slot] = true;
|
||||
*i = slot_u32;
|
||||
}
|
||||
|
||||
if !collision {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
let nonce = nonce;
|
||||
let slots = slots;
|
||||
|
||||
if collision {
|
||||
return Err(anyhow!("Failed to find a suitable nonce"));
|
||||
}
|
||||
|
||||
// FIXME: use iterator version.
|
||||
let (aux_pow_id_raw, aux_pow_raw) = {
|
||||
let mut aux_pow_id_raw = Vec::<[u8; 32]>::with_capacity(len);
|
||||
let mut aux_pow_raw = Vec::<[u8; 32]>::with_capacity(len);
|
||||
|
||||
assert_eq!(
|
||||
aux_pow.len(),
|
||||
slots.len(),
|
||||
"these need to be the same or else the below .zip() doesn't make sense"
|
||||
);
|
||||
|
||||
for (aux_pow, slot) in aux_pow.iter().zip(&slots) {
|
||||
if u32_to_usize(*slot) >= len {
|
||||
return Err(anyhow!("Slot value out of range"));
|
||||
}
|
||||
|
||||
aux_pow_id_raw.push(aux_pow.id);
|
||||
aux_pow_raw.push(aux_pow.hash);
|
||||
}
|
||||
|
||||
assert_eq!(
|
||||
slots.len(),
|
||||
aux_pow_raw.len(),
|
||||
"these need to be the same or else the below .zip() doesn't make sense"
|
||||
);
|
||||
assert_eq!(
|
||||
aux_pow_raw.len(),
|
||||
aux_pow_id_raw.len(),
|
||||
"these need to be the same or else the below .zip() doesn't make sense"
|
||||
);
|
||||
|
||||
for (slot, aux_pow) in slots.iter().zip(&aux_pow) {
|
||||
let slot = u32_to_usize(*slot);
|
||||
|
||||
if slot >= len {
|
||||
return Err(anyhow!("Slot value out of range"));
|
||||
}
|
||||
|
||||
aux_pow_raw[slot] = aux_pow.hash;
|
||||
aux_pow_id_raw[slot] = aux_pow.id;
|
||||
}
|
||||
|
||||
(
|
||||
aux_pow_id_raw.into_boxed_slice(),
|
||||
aux_pow_raw.into_boxed_slice(),
|
||||
)
|
||||
};
|
||||
|
||||
fn tree_hash(aux_pow_raw: &[[u8; 32]]) -> [u8; 32] {
|
||||
todo!("https://github.com/monero-project/monero/blob/cc73fe71162d564ffda8e549b79a350bca53c454/src/rpc/core_rpc_server.cpp#L2163")
|
||||
}
|
||||
|
||||
fn encode_mm_depth(aux_pow_len: usize, nonce: u32) -> u64 {
|
||||
todo!("https://github.com/monero-project/monero/blob/893916ad091a92e765ce3241b94e706ad012b62a/src/cryptonote_basic/merge_mining.cpp#L74")
|
||||
}
|
||||
|
||||
let merkle_root = tree_hash(aux_pow_raw.as_ref());
|
||||
let merkle_tree_depth = encode_mm_depth(len, nonce);
|
||||
|
||||
let block_template = {
|
||||
let hex = hex::decode(request.blocktemplate_blob)?;
|
||||
Block::read(&mut hex.as_slice())?
|
||||
};
|
||||
|
||||
fn remove_field_from_tx_extra() -> Result<(), ()> {
|
||||
todo!("https://github.com/monero-project/monero/blob/master/src/cryptonote_basic/cryptonote_format_utils.cpp#L767")
|
||||
}
|
||||
|
||||
if remove_field_from_tx_extra().is_err() {
|
||||
return Err(anyhow!("Error removing existing merkle root"));
|
||||
}
|
||||
|
||||
fn add_mm_merkle_root_to_tx_extra() -> Result<(), ()> {
|
||||
todo!("https://github.com/monero-project/monero/blob/cc73fe71162d564ffda8e549b79a350bca53c454/src/rpc/core_rpc_server.cpp#L2189
|
||||
")
|
||||
}
|
||||
|
||||
if add_mm_merkle_root_to_tx_extra().is_err() {
|
||||
return Err(anyhow!("Error adding merkle root"));
|
||||
}
|
||||
|
||||
fn invalidate_hashes() {
|
||||
// block_template.invalidate_hashes();
|
||||
// block_template.miner_tx.invalidate_hashes();
|
||||
// <https://github.com/monero-project/monero/blob/cc73fe71162d564ffda8e549b79a350bca53c454/src/rpc/core_rpc_server.cpp#L2195-L2196>
|
||||
todo!();
|
||||
}
|
||||
|
||||
invalidate_hashes();
|
||||
|
||||
let blocktemplate_blob = block_template.serialize();
|
||||
let blockhashing_blob = block_template.serialize_pow_hash();
|
||||
|
||||
let blocktemplate_blob = hex::encode(blocktemplate_blob);
|
||||
let blockhashing_blob = hex::encode(blockhashing_blob);
|
||||
let merkle_root = hex::encode(merkle_root);
|
||||
let aux_pow = IntoIterator::into_iter(aux_pow) // must be explicit due to `boxed_slice_into_iter`
|
||||
.map(|aux| AuxPow {
|
||||
id: hex::encode(aux.id),
|
||||
hash: hex::encode(aux.hash),
|
||||
})
|
||||
.collect::<Vec<AuxPow>>();
|
||||
|
||||
// --- END AUX POW IMPL ---
|
||||
|
||||
Ok(AddAuxPowResponse {
|
||||
base: ResponseBase::OK,
|
||||
blocktemplate_blob,
|
||||
blockhashing_blob,
|
||||
merkle_root,
|
||||
merkle_tree_depth: resp.merkle_tree_depth,
|
||||
merkle_tree_depth,
|
||||
aux_pow,
|
||||
})
|
||||
}
|
||||
|
|
|
@ -73,17 +73,22 @@ pub(crate) async fn fee_estimate(
|
|||
pub(crate) async fn calculate_pow(
|
||||
blockchain_context: &mut BlockChainContextService,
|
||||
hardfork: HardFork,
|
||||
height: u64,
|
||||
block: Box<Block>,
|
||||
block: Block,
|
||||
seed_hash: [u8; 32],
|
||||
) -> Result<[u8; 32], Error> {
|
||||
let Some(height) = block.number() else {
|
||||
return Err(anyhow!("block is missing height"));
|
||||
};
|
||||
|
||||
let block = Box::new(block);
|
||||
|
||||
let BlockChainContextResponse::CalculatePow(hash) = blockchain_context
|
||||
.ready()
|
||||
.await
|
||||
.map_err(|e| anyhow!(e))?
|
||||
.call(BlockChainContextRequest::CalculatePow {
|
||||
hardfork,
|
||||
height: u64_to_usize(height),
|
||||
height,
|
||||
block,
|
||||
seed_hash,
|
||||
})
|
||||
|
|
Loading…
Reference in a new issue