mirror of
https://github.com/Cuprate/cuprate.git
synced 2025-01-22 18:54:34 +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
|
clippy::too_many_lines
|
||||||
)
|
)
|
||||||
)]
|
)]
|
||||||
|
extern crate core;
|
||||||
|
|
||||||
// Only allow building 64-bit targets.
|
// Only allow building 64-bit targets.
|
||||||
//
|
//
|
||||||
// This allows us to assume 64-bit
|
// 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 bytemuck::TransparentWrapper;
|
||||||
use cuprate_helper::map::split_u128_into_low_high_bits;
|
use cuprate_database::{DatabaseRo, DatabaseRw, RuntimeError, StorableVec};
|
||||||
use cuprate_types::{AltBlockInformation, Chain, VerifiedTransactionInformation};
|
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::{
|
use crate::{
|
||||||
tables::TablesMut,
|
ops::block::{get_block_extended_header_from_height, get_block_info},
|
||||||
types::{AltBlockHeight, AltChainInfo, AltTransactionInfo, BlockHash, CompactAltBlockInfo},
|
tables::{Tables, TablesMut},
|
||||||
|
types::{
|
||||||
|
AltBlockHeight, AltChainInfo, AltTransactionInfo, BlockHash, BlockHeight,
|
||||||
|
CompactAltBlockInfo,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn add_alt_block(
|
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
|
//---------------------------------------------------------------------------------------------------- Import
|
||||||
use bytemuck::TransparentWrapper;
|
use bytemuck::TransparentWrapper;
|
||||||
use monero_serai::block::Block;
|
use monero_serai::block::{Block, BlockHeader};
|
||||||
|
|
||||||
use cuprate_database::{
|
use cuprate_database::{
|
||||||
RuntimeError, StorableVec, {DatabaseRo, DatabaseRw},
|
RuntimeError, StorableVec, {DatabaseRo, DatabaseRw},
|
||||||
|
@ -190,7 +190,7 @@ pub fn get_block_extended_header_from_height(
|
||||||
) -> Result<ExtendedBlockHeader, RuntimeError> {
|
) -> Result<ExtendedBlockHeader, RuntimeError> {
|
||||||
let block_info = tables.block_infos().get(block_height)?;
|
let block_info = tables.block_infos().get(block_height)?;
|
||||||
let block_blob = tables.block_blobs().get(block_height)?.0;
|
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(
|
let cumulative_difficulty = combine_low_high_bits_to_u128(
|
||||||
block_info.cumulative_difficulty_low,
|
block_info.cumulative_difficulty_low,
|
||||||
|
@ -201,10 +201,10 @@ pub fn get_block_extended_header_from_height(
|
||||||
#[allow(clippy::cast_possible_truncation)]
|
#[allow(clippy::cast_possible_truncation)]
|
||||||
Ok(ExtendedBlockHeader {
|
Ok(ExtendedBlockHeader {
|
||||||
cumulative_difficulty,
|
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"),
|
.expect("Stored block must have a valid hard-fork"),
|
||||||
vote: block.header.hardfork_signal,
|
vote: block_header.hardfork_signal,
|
||||||
timestamp: block.header.timestamp,
|
timestamp: block_header.timestamp,
|
||||||
block_weight: block_info.weight as usize,
|
block_weight: block_info.weight as usize,
|
||||||
long_term_weight: block_info.long_term_weight as usize,
|
long_term_weight: block_info.long_term_weight as usize,
|
||||||
})
|
})
|
||||||
|
|
|
@ -102,12 +102,12 @@
|
||||||
//! # Ok(()) }
|
//! # Ok(()) }
|
||||||
//! ```
|
//! ```
|
||||||
|
|
||||||
|
pub mod alt_block;
|
||||||
pub mod block;
|
pub mod block;
|
||||||
pub mod blockchain;
|
pub mod blockchain;
|
||||||
pub mod key_image;
|
pub mod key_image;
|
||||||
pub mod output;
|
pub mod output;
|
||||||
pub mod property;
|
pub mod property;
|
||||||
pub mod tx;
|
pub mod tx;
|
||||||
pub mod alt_block;
|
|
||||||
|
|
||||||
mod macros;
|
mod macros;
|
||||||
|
|
|
@ -22,6 +22,7 @@ use cuprate_types::{
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
ops::{
|
ops::{
|
||||||
|
alt_block::{alt_block_hash, alt_extended_headers_in_range},
|
||||||
block::{
|
block::{
|
||||||
block_exists, get_block_extended_header_from_height, get_block_height, get_block_info,
|
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},
|
free::{compact_history_genesis_not_included, compact_history_index_to_height_offset},
|
||||||
types::{BlockchainReadHandle, ResponseResult},
|
types::{BlockchainReadHandle, ResponseResult},
|
||||||
},
|
},
|
||||||
tables::{BlockHeights, BlockInfos, OpenTables, Tables},
|
tables::{AltBlockHeights, BlockHeights, BlockInfos, OpenTables, Tables},
|
||||||
types::{Amount, AmountIndex, BlockHash, BlockHeight, KeyImage, PreRctOutputId},
|
types::{Amount, AmountIndex, BlockHash, BlockHeight, KeyImage, PreRctOutputId},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -87,7 +88,7 @@ fn map_request(
|
||||||
match request {
|
match request {
|
||||||
R::BlockExtendedHeader(block) => block_extended_header(env, block),
|
R::BlockExtendedHeader(block) => block_extended_header(env, block),
|
||||||
R::BlockHash(block, chain) => block_hash(env, block, chain),
|
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::FilterUnknownHashes(hashes) => filter_unknown_hashes(env, hashes),
|
||||||
R::BlockExtendedHeaderInRange(range, chain) => {
|
R::BlockExtendedHeaderInRange(range, chain) => {
|
||||||
block_extended_header_in_range(env, 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 {
|
let block_hash = match chain {
|
||||||
Chain::Main => get_block_info(&block_height, &table_block_infos)?.block_hash,
|
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))
|
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`].
|
/// [`BlockchainReadRequest::FilterUnknownHashes`].
|
||||||
#[inline]
|
#[inline]
|
||||||
fn filter_unknown_hashes(env: &ConcreteEnv, mut hashes: HashSet<BlockHash>) -> ResponseResult {
|
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)
|
get_block_extended_header_from_height(&block_height, tables)
|
||||||
})
|
})
|
||||||
.collect::<Result<Vec<ExtendedBlockHeader>, RuntimeError>>()?,
|
.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))
|
Ok(BlockchainResponse::BlockExtendedHeaderInRange(vec))
|
||||||
|
|
Loading…
Reference in a new issue