diff --git a/storage/blockchain/src/ops/alt_block.rs b/storage/blockchain/src/ops/alt_block.rs new file mode 100644 index 00000000..d04899ef --- /dev/null +++ b/storage/blockchain/src/ops/alt_block.rs @@ -0,0 +1,104 @@ +use bytemuck::TransparentWrapper; + +use cuprate_database::{DatabaseRw, RuntimeError, StorableVec, DatabaseRo}; +use cuprate_helper::map::split_u128_into_low_high_bits; +use cuprate_types::{AltBlockInformation, Chain, VerifiedTransactionInformation}; + +use crate::{ + tables::TablesMut, + types::{AltBlockHeight, AltChainInfo, AltTransactionInfo, BlockHash, CompactAltBlockInfo}, +}; + +pub fn add_alt_block( + alt_block: &AltBlockInformation, + tables: &mut impl TablesMut, +) -> Result<(), RuntimeError> { + let alt_block_height = AltBlockHeight { + chain_id: alt_block.chain_id.into(), + height: alt_block.height, + }; + + tables + .alt_block_heights_mut() + .put(&alt_block.block_hash, &alt_block_height)?; + + check_add_alt_chain_info(&alt_block_height, &alt_block.block.header.previous, tables)?; + + let (cumulative_difficulty_low, cumulative_difficulty_high) = + split_u128_into_low_high_bits(alt_block.cumulative_difficulty); + + let alt_block_info = CompactAltBlockInfo { + block_hash: alt_block.block_hash, + pow_hash: alt_block.pow_hash, + height: alt_block.height, + weight: alt_block.weight, + long_term_weight: alt_block.long_term_weight, + cumulative_difficulty_low, + cumulative_difficulty_high, + }; + + tables + .alt_blocks_info_mut() + .put(&alt_block_height, &alt_block_info)?; + + tables.alt_block_blobs_mut().put( + &alt_block_height, + StorableVec::wrap_ref(&alt_block.block_blob), + )?; + + for tx in &alt_block.txs { + add_alt_transaction(&tx, tables)?; + } + + Ok(()) +} + +pub fn add_alt_transaction( + tx: &VerifiedTransactionInformation, + tables: &mut impl TablesMut, +) -> Result<(), RuntimeError> { + if tables.tx_ids().get(&tx.tx_hash).is_ok() + || tables.alt_transaction_infos().get(&tx.tx_hash).is_ok() + { + return Ok(()); + } + + tables.alt_transaction_infos_mut().put( + &tx.tx_hash, + &AltTransactionInfo { + tx_weight: tx.tx_weight, + fee: tx.fee, + tx_hash: tx.tx_hash, + }, + )?; + + tables + .alt_transaction_blobs_mut() + .put(&tx.tx_hash, StorableVec::wrap_ref(&tx.tx_blob)) +} + +pub fn check_add_alt_chain_info( + alt_block_height: &AltBlockHeight, + prev_hash: &BlockHash, + tables: &mut impl TablesMut, +) -> Result<(), RuntimeError> { + match tables.alt_chain_infos().get(&alt_block_height.chain_id) { + Ok(_) => return Ok(()), + Err(RuntimeError::KeyNotFound) => (), + Err(e) => return Err(e), + } + + let parent_chain = match tables.alt_block_heights().get(prev_hash) { + Ok(alt_parent_height) => Chain::Alt(alt_parent_height.chain_id.into()), + Err(RuntimeError::KeyNotFound) => Chain::Main, + Err(e) => return Err(e), + }; + + tables.alt_chain_infos_mut().put( + &alt_block_height.chain_id, + &AltChainInfo { + parent_chain: parent_chain.into(), + common_ancestor_height: alt_block_height.height - 1, + }, + ) +} diff --git a/storage/blockchain/src/ops/mod.rs b/storage/blockchain/src/ops/mod.rs index 4ff7dff1..1ec9c237 100644 --- a/storage/blockchain/src/ops/mod.rs +++ b/storage/blockchain/src/ops/mod.rs @@ -108,5 +108,6 @@ pub mod key_image; pub mod output; pub mod property; pub mod tx; +pub mod alt_block; mod macros; diff --git a/storage/blockchain/src/tables.rs b/storage/blockchain/src/tables.rs index 6db76816..381430d7 100644 --- a/storage/blockchain/src/tables.rs +++ b/storage/blockchain/src/tables.rs @@ -16,7 +16,12 @@ //! accessing _all_ tables defined here at once. //---------------------------------------------------------------------------------------------------- Import -use crate::types::{Amount, AmountIndex, AmountIndices, BlockBlob, BlockHash, BlockHeight, BlockInfo, KeyImage, Output, PreRctOutputId, PrunableBlob, PrunableHash, PrunedBlob, RctOutput, TxBlob, TxHash, TxId, UnlockTime, RawChainId, AltChainInfo, AltBlockHeight, CompactAltBlockInfo, AltTransactionInfo}; +use crate::types::{ + AltBlockHeight, AltChainInfo, AltTransactionInfo, Amount, AmountIndex, AmountIndices, + BlockBlob, BlockHash, BlockHeight, BlockInfo, CompactAltBlockInfo, KeyImage, Output, + PreRctOutputId, PrunableBlob, PrunableHash, PrunedBlob, RawChainId, RctOutput, TxBlob, TxHash, + TxId, UnlockTime, +}; //---------------------------------------------------------------------------------------------------- Tables // Notes: diff --git a/storage/blockchain/src/types.rs b/storage/blockchain/src/types.rs index 73c7614f..88ece10b 100644 --- a/storage/blockchain/src/types.rs +++ b/storage/blockchain/src/types.rs @@ -348,6 +348,14 @@ impl From for Chain { } } +impl From for RawChain { + fn from(value: RawChainId) -> Self { + assert_ne!(value.0, 0); + + RawChain(value.0) + } +} + //---------------------------------------------------------------------------------------------------- RawChainId #[derive(Copy, Clone, Debug, PartialEq, PartialOrd, Eq, Ord, Hash, Pod, Zeroable)] #[repr(transparent)] @@ -371,16 +379,16 @@ impl Key for RawChainId {} #[derive(Copy, Clone, Debug, PartialEq, PartialOrd, Eq, Ord, Hash, Pod, Zeroable)] #[repr(C)] pub struct AltChainInfo { - parent_chain: RawChain, - common_ancestor_height: u64 + pub parent_chain: RawChain, + pub common_ancestor_height: usize, } //---------------------------------------------------------------------------------------------------- AltBlockHeight #[derive(Copy, Clone, Debug, PartialEq, PartialOrd, Eq, Ord, Hash, Pod, Zeroable)] #[repr(C)] pub struct AltBlockHeight { - chain_id: u64, - height: u64, + pub chain_id: RawChainId, + pub height: usize, } impl Key for AltBlockHeight {} @@ -396,7 +404,7 @@ pub struct CompactAltBlockInfo { /// The block's proof-of-work hash. pub pow_hash: [u8; 32], /// The block's height. - pub height: u64, + pub height: usize, /// The adjusted block size, in bytes. pub weight: usize, /// The long term block weight, which is the weight factored in with previous block weights. @@ -404,7 +412,6 @@ pub struct CompactAltBlockInfo { /// The cumulative difficulty of all blocks up until and including this block. pub cumulative_difficulty_low: u64, pub cumulative_difficulty_high: u64, - } //---------------------------------------------------------------------------------------------------- AltTransactionInfo