mirror of
https://github.com/Cuprate/cuprate.git
synced 2025-01-22 10:44:36 +00:00
resolve current todo!s
This commit is contained in:
parent
e1ae848369
commit
ed887a7c85
5 changed files with 178 additions and 16 deletions
|
@ -98,6 +98,8 @@
|
|||
clippy::too_many_lines
|
||||
)
|
||||
)]
|
||||
extern crate core;
|
||||
|
||||
// Only allow building 64-bit targets.
|
||||
//
|
||||
// This allows us to assume 64-bit
|
||||
|
|
|
@ -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(¤t_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,
|
||||
})
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
})
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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))
|
||||
|
|
Loading…
Reference in a new issue