mirror of
https://github.com/hinto-janai/cuprate.git
synced 2024-12-22 19:49:33 +00:00
json_rpc: get_block_template
This commit is contained in:
parent
1719d7db84
commit
b402c82557
9 changed files with 137 additions and 81 deletions
|
@ -3,6 +3,7 @@
|
|||
use std::task::{Context, Poll};
|
||||
|
||||
use anyhow::Error;
|
||||
use cuprate_types::BlockTemplate;
|
||||
use futures::future::BoxFuture;
|
||||
use monero_serai::block::Block;
|
||||
use tower::Service;
|
||||
|
@ -84,6 +85,13 @@ pub enum BlockchainManagerRequest {
|
|||
//
|
||||
/// Get the next [`PruningSeed`] needed for a pruned sync.
|
||||
NextNeededPruningSeed,
|
||||
|
||||
/// TODO
|
||||
CreateBlockTemplate {
|
||||
prev_block: [u8; 32],
|
||||
account_public_address: String,
|
||||
extra_nonce: Vec<u8>,
|
||||
},
|
||||
}
|
||||
|
||||
/// TODO: use real type when public.
|
||||
|
@ -129,6 +137,9 @@ pub enum BlockchainManagerResponse {
|
|||
// Spans(Vec<Span<Z::Addr>>),
|
||||
/// Response to [`BlockchainManagerRequest::NextNeededPruningSeed`].
|
||||
NextNeededPruningSeed(PruningSeed),
|
||||
|
||||
/// Response to [`BlockchainManagerRequest::CreateBlockTemplate`].
|
||||
CreateBlockTemplate(Box<BlockTemplate>),
|
||||
}
|
||||
|
||||
/// TODO: use real type when public.
|
||||
|
|
|
@ -20,6 +20,7 @@ use cuprate_constants::{
|
|||
};
|
||||
use cuprate_helper::{
|
||||
cast::{u32_to_usize, u64_to_usize, usize_to_u64},
|
||||
fmt::HexPrefix,
|
||||
map::split_u128_into_low_high_bits,
|
||||
};
|
||||
use cuprate_hex::Hex;
|
||||
|
@ -53,7 +54,7 @@ use cuprate_rpc_types::{
|
|||
};
|
||||
use cuprate_types::{
|
||||
rpc::{AuxPow, CoinbaseTxSum, GetMinerDataTxBacklogEntry, HardForkEntry, TxBacklogEntry},
|
||||
HardFork,
|
||||
BlockTemplate, HardFork,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
|
@ -160,65 +161,50 @@ async fn get_block_template(
|
|||
return Err(anyhow!("Mining to subaddress is not supported yet"));
|
||||
}
|
||||
|
||||
// block b;
|
||||
// cryptonote::blobdata blob_reserve;
|
||||
// size_t reserved_offset;
|
||||
// if(!request.extra_nonce.empty())
|
||||
// {
|
||||
// if(!string_tools::parse_hexstr_to_binbuff(request.extra_nonce, blob_reserve))
|
||||
// {
|
||||
// error_resp.code = CORE_RPC_ERROR_CODE_WRONG_PARAM;
|
||||
// error_resp.message = "Parameter extra_nonce should be a hex string";
|
||||
// return false;
|
||||
// }
|
||||
// }
|
||||
// else
|
||||
// blob_reserve.resize(request.reserve_size, 0);
|
||||
// cryptonote::difficulty_type wdiff;
|
||||
// crypto::hash prev_block;
|
||||
// if (!request.prev_block.empty())
|
||||
// {
|
||||
// if (!epee::string_tools::hex_to_pod(request.prev_block, prev_block))
|
||||
// {
|
||||
// error_resp.code = CORE_RPC_ERROR_CODE_INTERNAL_ERROR;
|
||||
// error_resp.message = "Invalid prev_block";
|
||||
// return false;
|
||||
// }
|
||||
// }
|
||||
// crypto::hash seed_hash, next_seed_hash;
|
||||
// if (!get_block_template(info.address, request.prev_block.empty() ? NULL : &prev_block, blob_reserve, reserved_offset, wdiff, res.height, res.expected_reward, res.cumulative_weight, b, res.seed_height, seed_hash, next_seed_hash, error_resp))
|
||||
// return false;
|
||||
// if (b.major_version >= RX_BLOCK_VERSION)
|
||||
// {
|
||||
// res.seed_hash = string_tools::pod_to_hex(seed_hash);
|
||||
// if (seed_hash != next_seed_hash)
|
||||
// res.next_seed_hash = string_tools::pod_to_hex(next_seed_hash);
|
||||
// }
|
||||
let blob_reserve = hex::decode(request.extra_nonce)?;
|
||||
let prev_block = helper::hex_to_hash(request.prev_block)?;
|
||||
let extra_nonce = hex::decode(request.extra_nonce)?;
|
||||
|
||||
// res.reserved_offset = reserved_offset;
|
||||
// store_difficulty(wdiff, res.difficulty, res.wide_difficulty, res.difficulty_top64);
|
||||
// blobdata block_blob = t_serializable_object_to_blob(b);
|
||||
// blobdata hashing_blob = get_block_hashing_blob(b);
|
||||
// res.prev_hash = string_tools::pod_to_hex(b.prev_id);
|
||||
// res.blocktemplate_blob = string_tools::buff_to_hex_nodelimer(block_blob);
|
||||
// res.blockhashing_blob = string_tools::buff_to_hex_nodelimer(hashing_blob);
|
||||
// res.status = CORE_RPC_STATUS_OK;
|
||||
// return true;
|
||||
let BlockTemplate {
|
||||
block,
|
||||
reserved_offset,
|
||||
difficulty,
|
||||
height,
|
||||
expected_reward,
|
||||
seed_height,
|
||||
seed_hash,
|
||||
next_seed_hash,
|
||||
} = *blockchain_manager::create_block_template(
|
||||
&mut state.blockchain_manager,
|
||||
prev_block,
|
||||
request.wallet_address,
|
||||
extra_nonce,
|
||||
)
|
||||
.await?;
|
||||
|
||||
let blockhashing_blob = hex::encode(block.serialize_pow_hash());
|
||||
let blocktemplate_blob = hex::encode(block.serialize());
|
||||
let (difficulty, difficulty_top64) = split_u128_into_low_high_bits(difficulty);
|
||||
// let next_seed_hash = Hex(next_seed_hash);
|
||||
let next_seed_hash = hex::encode(next_seed_hash);
|
||||
let prev_hash = Hex(block.header.previous);
|
||||
let seed_hash = Hex(seed_hash);
|
||||
let wide_difficulty = (difficulty, difficulty_top64).hex_prefix();
|
||||
|
||||
Ok(GetBlockTemplateResponse {
|
||||
base: ResponseBase::OK,
|
||||
blockhashing_blob: todo!(),
|
||||
blocktemplate_blob: todo!(),
|
||||
difficulty_top64: todo!(),
|
||||
difficulty: todo!(),
|
||||
expected_reward: todo!(),
|
||||
height: todo!(),
|
||||
next_seed_hash: todo!(),
|
||||
prev_hash: todo!(),
|
||||
reserved_offset: todo!(),
|
||||
seed_hash: todo!(),
|
||||
seed_height: todo!(),
|
||||
wide_difficulty: todo!(),
|
||||
blockhashing_blob,
|
||||
blocktemplate_blob,
|
||||
difficulty_top64,
|
||||
difficulty,
|
||||
expected_reward,
|
||||
height,
|
||||
next_seed_hash,
|
||||
prev_hash,
|
||||
reserved_offset,
|
||||
seed_hash,
|
||||
seed_height,
|
||||
wide_difficulty,
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@ use cuprate_constants::rpc::{
|
|||
MAX_RESTRICTED_GLOBAL_FAKE_OUTS_COUNT, RESTRICTED_SPENT_KEY_IMAGES_COUNT,
|
||||
};
|
||||
use cuprate_helper::cast::usize_to_u64;
|
||||
use cuprate_hex::Hex;
|
||||
use cuprate_rpc_interface::RpcHandler;
|
||||
use cuprate_rpc_types::{
|
||||
base::{AccessResponseBase, ResponseBase},
|
||||
|
@ -100,7 +101,7 @@ async fn get_height(
|
|||
request: GetHeightRequest,
|
||||
) -> Result<GetHeightResponse, Error> {
|
||||
let (height, hash) = helper::top_height(&mut state).await?;
|
||||
let hash = hex::encode(hash);
|
||||
let hash = Hex(hash);
|
||||
|
||||
Ok(GetHeightResponse {
|
||||
base: ResponseBase::OK,
|
||||
|
@ -142,9 +143,8 @@ async fn is_key_image_spent(
|
|||
|
||||
let mut spent_status = Vec::with_capacity(request.key_images.len());
|
||||
|
||||
for hex in request.key_images {
|
||||
let key_image = helper::hex_to_hash(hex)?;
|
||||
let status = helper::key_image_spent(&mut state, key_image).await?;
|
||||
for key_image in request.key_images {
|
||||
let status = helper::key_image_spent(&mut state, key_image.0).await?;
|
||||
spent_status.push(status.to_u8());
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
//! Functions to send [`BlockchainManagerRequest`]s.
|
||||
|
||||
use anyhow::Error;
|
||||
use cuprate_types::BlockTemplate;
|
||||
use monero_serai::block::Block;
|
||||
use tower::{Service, ServiceExt};
|
||||
|
||||
|
@ -218,3 +219,26 @@ pub(crate) async fn next_needed_pruning_seed(
|
|||
|
||||
Ok(seed)
|
||||
}
|
||||
|
||||
/// [`BlockchainManagerRequest::CreateBlockTemplate`]
|
||||
pub(crate) async fn create_block_template(
|
||||
blockchain_manager: &mut BlockchainManagerHandle,
|
||||
prev_block: [u8; 32],
|
||||
account_public_address: String,
|
||||
extra_nonce: Vec<u8>,
|
||||
) -> Result<Box<BlockTemplate>, Error> {
|
||||
let BlockchainManagerResponse::CreateBlockTemplate(block_template) = blockchain_manager
|
||||
.ready()
|
||||
.await?
|
||||
.call(BlockchainManagerRequest::CreateBlockTemplate {
|
||||
prev_block,
|
||||
account_public_address,
|
||||
extra_nonce,
|
||||
})
|
||||
.await?
|
||||
else {
|
||||
unreachable!();
|
||||
};
|
||||
|
||||
Ok(block_template)
|
||||
}
|
||||
|
|
|
@ -1,18 +1,41 @@
|
|||
//! Formatting.
|
||||
|
||||
use crate::map::combine_low_high_bits_to_u128;
|
||||
pub trait HexPrefix {
|
||||
fn hex_prefix(self) -> String;
|
||||
}
|
||||
|
||||
/// Format two [`u64`]'s as a [`u128`] as a lower-case hexadecimal string prefixed with `0x`.
|
||||
///
|
||||
/// ```rust
|
||||
/// # use cuprate_helper::fmt::hex_prefix_u128;
|
||||
/// assert_eq!(hex_prefix_u128(0, 0), "0x0");
|
||||
/// assert_eq!(hex_prefix_u128(0, u64::MAX), "0xffffffffffffffff0000000000000000");
|
||||
/// assert_eq!(hex_prefix_u128(u64::MAX, 0), "0xffffffffffffffff");
|
||||
/// assert_eq!(hex_prefix_u128(u64::MAX, u64::MAX), "0xffffffffffffffffffffffffffffffff");
|
||||
/// ```
|
||||
pub fn hex_prefix_u128(low_bits: u64, high_bits: u64) -> String {
|
||||
format!("{:#x}", combine_low_high_bits_to_u128(low_bits, high_bits))
|
||||
macro_rules! impl_hex_prefix {
|
||||
($(
|
||||
$t:ty
|
||||
),*) => {
|
||||
$(
|
||||
impl HexPrefix for $t {
|
||||
fn hex_prefix(self) -> String {
|
||||
format!("{:#x}", self)
|
||||
}
|
||||
}
|
||||
)*
|
||||
};
|
||||
}
|
||||
|
||||
impl_hex_prefix!(u8, u16, u32, u64, u128, i8, i16, i32, i64, i128, usize, isize);
|
||||
|
||||
impl HexPrefix for (u64, u64) {
|
||||
/// Combine the low and high bits of a [`u128`] as a lower-case hexadecimal string prefixed with `0x`.
|
||||
///
|
||||
/// ```rust
|
||||
/// # use cuprate_helper::fmt::HexPrefix;
|
||||
/// assert_eq!((0, 0).hex_prefix(), "0x0");
|
||||
/// assert_eq!((0, u64::MAX).hex_prefix(), "0xffffffffffffffff0000000000000000");
|
||||
/// assert_eq!((u64::MAX, 0).hex_prefix(), "0xffffffffffffffff");
|
||||
/// assert_eq!((u64::MAX, u64::MAX).hex_prefix(), "0xffffffffffffffffffffffffffffffff");
|
||||
/// ```
|
||||
fn hex_prefix(self) -> String {
|
||||
format!(
|
||||
"{:#x}",
|
||||
crate::map::combine_low_high_bits_to_u128(self.0, self.1)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
|
|
@ -7,7 +7,7 @@ use std::{
|
|||
time::Duration,
|
||||
};
|
||||
|
||||
use cuprate_helper::{fmt::hex_prefix_u128, map::ipv4_from_u32};
|
||||
use cuprate_helper::{fmt::HexPrefix, map::ipv4_from_u32};
|
||||
use cuprate_hex::Hex;
|
||||
use cuprate_p2p_core::{
|
||||
types::{ConnectionId, ConnectionInfo, SetBan, Span},
|
||||
|
@ -40,11 +40,9 @@ impl From<BlockHeader> for crate::misc::BlockHeader {
|
|||
timestamp: x.timestamp,
|
||||
// FIXME: if we made a type that automatically did `hex_prefix_u128`,
|
||||
// we wouldn't need `crate::misc::BlockHeader`.
|
||||
wide_cumulative_difficulty: hex_prefix_u128(
|
||||
x.cumulative_difficulty,
|
||||
x.cumulative_difficulty_top64,
|
||||
),
|
||||
wide_difficulty: hex_prefix_u128(x.difficulty, x.difficulty_top64),
|
||||
wide_cumulative_difficulty: (x.cumulative_difficulty, x.cumulative_difficulty_top64)
|
||||
.hex_prefix(),
|
||||
wide_difficulty: (x.difficulty, x.difficulty_top64).hex_prefix(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -132,7 +130,7 @@ impl From<ChainInfo> for crate::misc::ChainInfo {
|
|||
height: x.height,
|
||||
length: x.length,
|
||||
main_chain_parent_block: Hex(x.main_chain_parent_block),
|
||||
wide_difficulty: hex_prefix_u128(x.difficulty, x.difficulty_top64),
|
||||
wide_difficulty: (x.difficulty, x.difficulty_top64).hex_prefix(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
1
types/hex/src/prefix.rs
Normal file
1
types/hex/src/prefix.rs
Normal file
|
@ -0,0 +1 @@
|
|||
|
|
@ -24,8 +24,8 @@ pub use transaction_verification_data::{
|
|||
CachedVerificationState, TransactionVerificationData, TxVersion,
|
||||
};
|
||||
pub use types::{
|
||||
AltBlockInformation, Chain, ChainId, ExtendedBlockHeader, OutputOnChain, TxsInBlock,
|
||||
VerifiedBlockInformation, VerifiedTransactionInformation,
|
||||
AltBlockInformation, BlockTemplate, Chain, ChainId, ExtendedBlockHeader, OutputOnChain,
|
||||
TxsInBlock, VerifiedBlockInformation, VerifiedTransactionInformation,
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------------------------------------- Feature-gated
|
||||
|
|
|
@ -154,6 +154,19 @@ pub struct TxsInBlock {
|
|||
pub txs: Vec<Vec<u8>>,
|
||||
}
|
||||
|
||||
/// A block template, used in RPC's `get_block_template`.
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub struct BlockTemplate {
|
||||
pub block: Block,
|
||||
pub reserved_offset: u64,
|
||||
pub difficulty: u128,
|
||||
pub height: u64,
|
||||
pub expected_reward: u64,
|
||||
pub seed_height: u64,
|
||||
pub seed_hash: [u8; 32],
|
||||
pub next_seed_hash: [u8; 32],
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------- Tests
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
|
|
Loading…
Reference in a new issue