Compare commits

...

2 commits

Author SHA1 Message Date
hinto.janai
c18ba6e5b0
lints
Some checks failed
Audit / audit (push) Has been cancelled
Deny / audit (push) Has been cancelled
2024-10-10 18:15:21 -04:00
hinto.janai
02e950bf56
small fixes, hardfork changes 2024-10-10 17:37:28 -04:00
10 changed files with 124 additions and 50 deletions

23
Cargo.lock generated
View file

@ -933,6 +933,7 @@ dependencies = [
"proptest-derive",
"serde",
"serde_json",
"strum",
"thiserror",
]
@ -2674,6 +2675,28 @@ dependencies = [
"spin",
]
[[package]]
name = "strum"
version = "0.26.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06"
dependencies = [
"strum_macros",
]
[[package]]
name = "strum_macros"
version = "0.26.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be"
dependencies = [
"heck",
"proc-macro2",
"quote",
"rustversion",
"syn 2.0.77",
]
[[package]]
name = "subtle"
version = "2.6.1"

View file

@ -78,6 +78,7 @@ rayon = { version = "1.10.0", default-features = false }
serde_bytes = { version = "0.11.15", default-features = false }
serde_json = { version = "1.0.128", default-features = false }
serde = { version = "1.0.210", default-features = false }
strum = { version = "0.26.3", default-features = false }
thiserror = { version = "1.0.63", default-features = false }
thread_local = { version = "1.1.8", default-features = false }
tokio-util = { version = "0.7.12", default-features = false }

View file

@ -9,6 +9,10 @@
unused_variables,
clippy::needless_pass_by_value,
clippy::unused_async,
clippy::diverging_sub_expression,
unused_mut,
clippy::let_unit_value,
clippy::needless_pass_by_ref_mut,
reason = "TODO: remove after v1.0.0"
)]

View file

@ -4,9 +4,9 @@
mod bin;
mod handler;
mod helper;
mod json;
mod other;
mod request;
mod helper;
pub use handler::CupratedRpcHandler;

View file

@ -92,7 +92,7 @@ pub(super) async fn block_header_by_hash(
let block = blockchain::block_by_hash(&mut state.blockchain_read, hash).await?;
let header: ExtendedBlockHeader = todo!(); //blockchain::block_extended_header_by_hash(state.blockchain_read, hash).await?;
let block_header = into_block_header(header.height, top_height, fill_pow_hash, block, header);
let block_header = into_block_header(todo!(), top_height, fill_pow_hash, block, header);
Ok(block_header)
}
@ -105,8 +105,7 @@ pub(super) async fn top_block_header(
let block: Block = todo!();
let header: ExtendedBlockHeader = todo!();
let block_header =
into_block_header(header.height, header.height, fill_pow_hash, block, header);
let block_header = into_block_header(todo!(), todo!(), fill_pow_hash, block, header);
Ok(block_header)
}
@ -148,7 +147,7 @@ pub(super) fn hex_to_hash(hex: String) -> Result<[u8; 32], Error> {
/// [`BlockchainResponse::ChainHeight`] minus 1.
pub(super) async fn top_height(state: &mut CupratedRpcHandler) -> Result<(u64, [u8; 32]), Error> {
let (chain_height, hash) = blockchain::chain_height(state).await?;
let (chain_height, hash) = blockchain::chain_height(&mut state.blockchain_read).await?;
let height = chain_height.saturating_sub(1);
Ok((height, hash))
}
@ -158,11 +157,12 @@ pub(super) async fn key_image_spent(
state: &mut CupratedRpcHandler,
key_image: [u8; 32],
) -> Result<KeyImageSpentStatus, Error> {
if blockchain::key_image_spent(state, key_image).await? {
Ok(KeyImageSpentStatus::SpentInBlockchain)
} else if todo!("key image is spent in tx pool") {
Ok(KeyImageSpentStatus::SpentInPool)
} else {
Ok(KeyImageSpentStatus::Unspent)
}
todo!("impl key image vec check responding KeyImageSpentStatus")
// if blockchain::key_image_spent(state, key_image).await? {
// Ok(KeyImageSpentStatus::SpentInBlockchain)
// } else if todo!("key image is spent in tx pool") {
// Ok(KeyImageSpentStatus::SpentInPool)
// } else {
// Ok(KeyImageSpentStatus::Unspent)
// }
}

View file

@ -8,9 +8,10 @@ use tower::{Service, ServiceExt};
use cuprate_consensus::{BlockchainReadRequest, BlockchainResponse};
use cuprate_constants::{
build::RELEASE,
rpc::{BLOCK_SIZE_SANITY_LEEWAY, RESTRICTED_BLOCK_COUNT, RESTRICTED_BLOCK_HEADER_RANGE},
rpc::{RESTRICTED_BLOCK_COUNT, RESTRICTED_BLOCK_HEADER_RANGE},
};
use cuprate_helper::cast::u64_to_usize;
use cuprate_rpc_interface::RpcHandler;
use cuprate_rpc_types::{
base::{AccessResponseBase, ResponseBase},
json::{
@ -114,7 +115,7 @@ async fn on_get_block_hash(
request: OnGetBlockHashRequest,
) -> Result<OnGetBlockHashResponse, Error> {
let [height] = request.block_height;
let hash = blockchain::block_hash(&mut state, height).await?;
let hash = blockchain::block_hash(&mut state.blockchain_read, height, todo!()).await?;
let block_hash = hex::encode(hash);
Ok(OnGetBlockHashResponse { block_hash })
@ -127,11 +128,11 @@ async fn submit_block(
) -> Result<SubmitBlockResponse, Error> {
let [blob] = request.block_blob;
let limit = blockchain::cumulative_block_weight_limit(&mut state).await?;
let limit = todo!(); //blockchain::cumulative_block_weight_limit(&mut state.blockchain_read).await?;
if blob.len() > limit + BLOCK_SIZE_SANITY_LEEWAY {
return Err(anyhow!("Block size is too big, rejecting block"));
}
// if blob.len() > limit + BLOCK_SIZE_SANITY_LEEWAY {
// return Err(anyhow!("Block size is too big, rejecting block"));
// }
let bytes = hex::decode(blob)?;
let block = Block::read(&mut bytes.as_slice())?;
@ -173,12 +174,12 @@ async fn get_last_block_header(
})
}
/// <https://github.com/monero-project/monero/blob/cc73fe71162d564ffda8e549b79a350bca53c454/src/rpc/core_rpc_server.cpp#L2468-L2498>
/// <https://github.com/monero-project/monero/blob/cc73fe71162d564ffda8e549b79a350bca53c454/src/rpc/core_rpc_server.cpp#L2500-L2567>
async fn get_block_header_by_hash(
mut state: CupratedRpcHandler,
request: GetBlockHeaderByHashRequest,
) -> Result<GetBlockHeaderByHashResponse, Error> {
if state.restricted && request.hashes.len() > RESTRICTED_BLOCK_COUNT {
if state.restricted() && request.hashes.len() > RESTRICTED_BLOCK_COUNT {
return Err(anyhow!(
"Too many block headers requested in restricted mode"
));
@ -239,7 +240,7 @@ async fn get_block_headers_range(
return Err(anyhow!("Invalid start/end heights"));
}
if state.restricted
if state.restricted()
&& request.end_height.saturating_sub(request.start_height) + 1
> RESTRICTED_BLOCK_HEADER_RANGE
{
@ -280,10 +281,10 @@ async fn get_block(
) -> Result<GetBlockResponse, Error> {
let block = if request.hash.is_empty() {
helper::check_height(&mut state, request.height).await?;
blockchain::block(&mut state, request.height).await?
blockchain::block(&mut state.blockchain_read, request.height).await?
} else {
let hash = helper::hex_to_hash(request.hash)?;
blockchain::block_by_hash(&mut state, hash).await?
blockchain::block_by_hash(&mut state.blockchain_read, hash).await?
};
Ok(todo!())
@ -375,7 +376,8 @@ async fn hard_fork_info(
let hard_fork = if request.version > 0 {
HardFork::from_version(request.version)?
} else {
blockchain::current_hard_fork(&mut state).await?
// blockchain::current_hard_fork(&mut state).await?
todo!()
};
Ok(HardForkInfoResponse {

View file

@ -817,8 +817,17 @@ define_request_and_response! {
hard_fork_info,
cc73fe71162d564ffda8e549b79a350bca53c454 =>
core_rpc_server_commands_defs.h => 1958..=1995,
HardForkInfo (empty),
Request {},
HardForkInfo,
#[doc = serde_doc_test!(
HARD_FORK_INFO => HardForkInfo {
version: 16,
}
)]
#[derive(Copy)]
Request {
version: u8,
},
#[doc = serde_doc_test!(
HARD_FORK_INFO_RESPONSE => HardForkInfoResponse {
@ -827,9 +836,9 @@ define_request_and_response! {
enabled: true,
state: 0,
threshold: 0,
version: 16,
version: 3,
votes: 10080,
voting: 16,
voting: 3,
window: 10080
}
)]

View file

@ -608,7 +608,10 @@ define_request_and_response! {
r#"{
"jsonrpc": "2.0",
"id": "0",
"method": "hard_fork_info"
"method": "hard_fork_info",
"params": {
"version": 16
}
}"#;
Response =
r#"{

View file

@ -27,6 +27,7 @@ curve25519-dalek = { workspace = true }
monero-serai = { workspace = true }
hex = { workspace = true, features = ["serde", "alloc"], optional = true }
serde = { workspace = true, features = ["derive"], optional = true }
strum = { workspace = true, features = ["derive"] }
thiserror = { workspace = true }
proptest = { workspace = true, optional = true }

View file

@ -1,6 +1,10 @@
//! The [`HardFork`] type.
use std::time::Duration;
use strum::{
AsRefStr, Display, EnumCount, EnumIs, EnumString, FromRepr, IntoStaticStr, VariantArray,
};
use monero_serai::block::BlockHeader;
/// Target block time for hf 1.
@ -27,7 +31,25 @@ pub enum HardForkError {
}
/// An identifier for every hard-fork Monero has had.
#[derive(Default, Debug, PartialEq, Eq, PartialOrd, Ord, Copy, Clone, Hash)]
#[derive(
Default,
Debug,
PartialEq,
Eq,
PartialOrd,
Ord,
Copy,
Clone,
Hash,
EnumCount,
Display,
AsRefStr,
EnumIs,
EnumString,
FromRepr,
IntoStaticStr,
VariantArray,
)]
#[cfg_attr(any(feature = "proptest"), derive(proptest_derive::Arbitrary))]
#[repr(u8)]
pub enum HardFork {
@ -52,6 +74,14 @@ pub enum HardFork {
}
impl HardFork {
/// TODO
///
/// ```rust
/// # use crate::hard_fork::HardFork;
/// assert_eq!(HardFork::CURRENT, HardFork::V16);
/// ```
pub const CURRENT: Self = Self::VARIANTS[Self::COUNT - 1];
/// Returns the hard-fork for a blocks [`BlockHeader::hardfork_version`] field.
///
/// ref: <https://monero-book.cuprate.org/consensus_rules/hardforks.html#blocks-version-and-vote>
@ -61,25 +91,21 @@ impl HardFork {
/// Will return [`Err`] if the version is not a valid [`HardFork`].
#[inline]
pub const fn from_version(version: u8) -> Result<Self, HardForkError> {
Ok(match version {
1 => Self::V1,
2 => Self::V2,
3 => Self::V3,
4 => Self::V4,
5 => Self::V5,
6 => Self::V6,
7 => Self::V7,
8 => Self::V8,
9 => Self::V9,
10 => Self::V10,
11 => Self::V11,
12 => Self::V12,
13 => Self::V13,
14 => Self::V14,
15 => Self::V15,
16 => Self::V16,
_ => return Err(HardForkError::HardForkUnknown),
})
#[expect(
clippy::cast_possible_truncation,
reason = "we check that `HardFork::COUNT` fits into a `u8`."
)]
const COUNT_AS_U8: u8 = {
const COUNT: usize = HardFork::COUNT;
assert!(COUNT <= u8::MAX as usize);
COUNT as u8
};
if version != 0 && version <= COUNT_AS_U8 {
Ok(Self::VARIANTS[(version - 1) as usize])
} else {
Err(HardForkError::HardForkUnknown)
}
}
/// Returns the hard-fork for a blocks [`BlockHeader::hardfork_signal`] (vote) field.
@ -92,7 +118,7 @@ impl HardFork {
return Self::V1;
}
// This must default to the latest hard-fork!
Self::from_version(vote).unwrap_or(Self::V16)
Self::from_version(vote).unwrap_or(Self::CURRENT)
}
/// Returns the [`HardFork`] version and vote from this block header.
@ -127,4 +153,9 @@ impl HardFork {
_ => BLOCK_TIME_V2,
}
}
/// TODO
pub const fn is_current(self) -> bool {
matches!(self, Self::CURRENT)
}
}