resolve current todo!s

This commit is contained in:
Boog900 2024-08-30 23:06:30 +01:00
parent e1ae848369
commit ed887a7c85
No known key found for this signature in database
GPG key ID: 42AB1287CB0041C2
5 changed files with 178 additions and 16 deletions

View file

@ -98,6 +98,8 @@
clippy::too_many_lines
)
)]
extern crate core;
// Only allow building 64-bit targets.
//
// This allows us to assume 64-bit

View file

@ -1,12 +1,21 @@
use bytemuck::TransparentWrapper;
use std::cmp::max;
use cuprate_database::{DatabaseRw, RuntimeError, StorableVec, DatabaseRo};
use cuprate_helper::map::split_u128_into_low_high_bits;
use cuprate_types::{AltBlockInformation, Chain, VerifiedTransactionInformation};
use bytemuck::TransparentWrapper;
use cuprate_database::{DatabaseRo, DatabaseRw, RuntimeError, StorableVec};
use cuprate_helper::map::{combine_low_high_bits_to_u128, split_u128_into_low_high_bits};
use cuprate_types::{
AltBlockInformation, Chain, ChainId, ExtendedBlockHeader, HardFork,
VerifiedTransactionInformation,
};
use monero_serai::block::BlockHeader;
use crate::{
tables::TablesMut,
types::{AltBlockHeight, AltChainInfo, AltTransactionInfo, BlockHash, CompactAltBlockInfo},
ops::block::{get_block_extended_header_from_height, get_block_info},
tables::{Tables, TablesMut},
types::{
AltBlockHeight, AltChainInfo, AltTransactionInfo, BlockHash, BlockHeight,
CompactAltBlockInfo,
},
};
pub fn add_alt_block(
@ -102,3 +111,119 @@ pub fn check_add_alt_chain_info(
},
)
}
pub fn alt_block_hash(
block_height: &BlockHeight,
alt_chain: ChainId,
tables: &mut impl Tables,
) -> Result<BlockHash, RuntimeError> {
let alt_chains = tables.alt_chain_infos();
let original_chain = {
let mut chain = alt_chain.into();
loop {
let chain_info = alt_chains.get(&chain)?;
if chain_info.common_ancestor_height < *block_height {
break Chain::Alt(chain.into());
}
match chain_info.parent_chain.into() {
Chain::Main => break Chain::Main,
Chain::Alt(alt_chain_id) => {
chain = alt_chain_id.into();
continue;
}
}
}
};
match original_chain {
Chain::Main => {
get_block_info(&block_height, tables.block_infos()).map(|info| info.block_hash)
}
Chain::Alt(chain_id) => tables
.alt_blocks_info()
.get(&AltBlockHeight {
chain_id: chain_id.into(),
height: *block_height,
})
.map(|info| info.block_hash),
}
}
pub fn alt_extended_headers_in_range(
range: std::ops::Range<BlockHeight>,
alt_chain: ChainId,
tables: &impl Tables,
) -> Result<Vec<ExtendedBlockHeader>, RuntimeError> {
// TODO: this function does not use rayon, however it probably should.
let mut ranges = Vec::with_capacity(5);
let alt_chains = tables.alt_chain_infos();
let mut i = range.end;
let mut current_chain_id = alt_chain.into();
while i > range.start {
let chain_info = alt_chains.get(&current_chain_id)?;
let start_height = max(range.start, chain_info.common_ancestor_height + 1);
ranges.push((chain_info.parent_chain.into(), start_height..i));
i = chain_info.common_ancestor_height;
match chain_info.parent_chain.into() {
Chain::Main => {
ranges.push((Chain::Main, range.start..i));
break;
}
Chain::Alt(alt_chain_id) => {
current_chain_id = alt_chain_id.into();
continue;
}
}
}
let res = ranges
.into_iter()
.rev()
.map(|(chain, range)| {
range.into_iter().map(move |height| match chain {
Chain::Main => get_block_extended_header_from_height(&height, tables),
Chain::Alt(chain_id) => get_alt_block_extended_header_from_height(
&AltBlockHeight {
chain_id: chain_id.into(),
height,
},
tables,
),
})
})
.flatten()
.collect::<Result<_, _>>()?;
Ok(res)
}
pub fn get_alt_block_extended_header_from_height(
height: &AltBlockHeight,
table: &impl Tables,
) -> Result<ExtendedBlockHeader, RuntimeError> {
let block_info = table.alt_blocks_info().get(height)?;
let block_blob = table.alt_block_blobs().get(height)?.0;
let block_header = BlockHeader::read(&mut block_blob.as_slice())?;
Ok(ExtendedBlockHeader {
version: HardFork::from_version(0).expect("Block in DB must have correct version"),
vote: block_header.hardfork_version,
timestamp: block_header.timestamp,
cumulative_difficulty: combine_low_high_bits_to_u128(
block_info.cumulative_difficulty_low,
block_info.cumulative_difficulty_high,
),
block_weight: block_info.weight,
long_term_weight: block_info.long_term_weight,
})
}

View file

@ -2,7 +2,7 @@
//---------------------------------------------------------------------------------------------------- Import
use bytemuck::TransparentWrapper;
use monero_serai::block::Block;
use monero_serai::block::{Block, BlockHeader};
use cuprate_database::{
RuntimeError, StorableVec, {DatabaseRo, DatabaseRw},
@ -190,7 +190,7 @@ pub fn get_block_extended_header_from_height(
) -> Result<ExtendedBlockHeader, RuntimeError> {
let block_info = tables.block_infos().get(block_height)?;
let block_blob = tables.block_blobs().get(block_height)?.0;
let block = Block::read(&mut block_blob.as_slice())?;
let block_header = BlockHeader::read(&mut block_blob.as_slice())?;
let cumulative_difficulty = combine_low_high_bits_to_u128(
block_info.cumulative_difficulty_low,
@ -201,10 +201,10 @@ pub fn get_block_extended_header_from_height(
#[allow(clippy::cast_possible_truncation)]
Ok(ExtendedBlockHeader {
cumulative_difficulty,
version: HardFork::from_version(block.header.hardfork_version)
version: HardFork::from_version(block_header.hardfork_version)
.expect("Stored block must have a valid hard-fork"),
vote: block.header.hardfork_signal,
timestamp: block.header.timestamp,
vote: block_header.hardfork_signal,
timestamp: block_header.timestamp,
block_weight: block_info.weight as usize,
long_term_weight: block_info.long_term_weight as usize,
})

View file

@ -102,12 +102,12 @@
//! # Ok(()) }
//! ```
pub mod alt_block;
pub mod block;
pub mod blockchain;
pub mod key_image;
pub mod output;
pub mod property;
pub mod tx;
pub mod alt_block;
mod macros;

View file

@ -22,6 +22,7 @@ use cuprate_types::{
use crate::{
ops::{
alt_block::{alt_block_hash, alt_extended_headers_in_range},
block::{
block_exists, get_block_extended_header_from_height, get_block_height, get_block_info,
},
@ -33,7 +34,7 @@ use crate::{
free::{compact_history_genesis_not_included, compact_history_index_to_height_offset},
types::{BlockchainReadHandle, ResponseResult},
},
tables::{BlockHeights, BlockInfos, OpenTables, Tables},
tables::{AltBlockHeights, BlockHeights, BlockInfos, OpenTables, Tables},
types::{Amount, AmountIndex, BlockHash, BlockHeight, KeyImage, PreRctOutputId},
};
@ -87,7 +88,7 @@ fn map_request(
match request {
R::BlockExtendedHeader(block) => block_extended_header(env, block),
R::BlockHash(block, chain) => block_hash(env, block, chain),
R::FindBlock(_) => todo!("Add alt blocks to DB"),
R::FindBlock(block_hash) => find_block(env, block_hash),
R::FilterUnknownHashes(hashes) => filter_unknown_hashes(env, hashes),
R::BlockExtendedHeaderInRange(range, chain) => {
block_extended_header_in_range(env, range, chain)
@ -198,12 +199,39 @@ fn block_hash(env: &ConcreteEnv, block_height: BlockHeight, chain: Chain) -> Res
let block_hash = match chain {
Chain::Main => get_block_info(&block_height, &table_block_infos)?.block_hash,
Chain::Alt(_) => todo!("Add alt blocks to DB"),
Chain::Alt(chain) => {
alt_block_hash(&block_height, chain, &mut env_inner.open_tables(&tx_ro)?)?
}
};
Ok(BlockchainResponse::BlockHash(block_hash))
}
/// [`BlockchainReadRequest::FindBlock`]
fn find_block(env: &ConcreteEnv, block_hash: BlockHash) -> ResponseResult {
// Single-threaded, no `ThreadLocal` required.
let env_inner = env.env_inner();
let tx_ro = env_inner.tx_ro()?;
let table_block_heights = env_inner.open_db_ro::<BlockHeights>(&tx_ro)?;
// Check the main chain first.
match table_block_heights.get(&block_hash) {
Ok(height) => return Ok(BlockchainResponse::FindBlock(Some((Chain::Main, height)))),
Err(RuntimeError::KeyNotFound) => (),
Err(e) => return Err(e),
}
let table_alt_block_heights = env_inner.open_db_ro::<AltBlockHeights>(&tx_ro)?;
let height = table_alt_block_heights.get(&block_hash)?;
Ok(BlockchainResponse::FindBlock(Some((
Chain::Alt(height.chain_id.into()),
height.height,
))))
}
/// [`BlockchainReadRequest::FilterUnknownHashes`].
#[inline]
fn filter_unknown_hashes(env: &ConcreteEnv, mut hashes: HashSet<BlockHash>) -> ResponseResult {
@ -254,7 +282,14 @@ fn block_extended_header_in_range(
get_block_extended_header_from_height(&block_height, tables)
})
.collect::<Result<Vec<ExtendedBlockHeader>, RuntimeError>>()?,
Chain::Alt(_) => todo!("Add alt blocks to DB"),
Chain::Alt(chain_id) => {
let tx_ro = tx_ro.get_or_try(|| env_inner.tx_ro())?;
alt_extended_headers_in_range(
range,
chain_id,
get_tables!(env_inner, tx_ro, tables)?.as_ref(),
)?
}
};
Ok(BlockchainResponse::BlockExtendedHeaderInRange(vec))