diff --git a/toolkit/data-sources/db-sync/src/block/mod.rs b/toolkit/data-sources/db-sync/src/block/mod.rs index ca517bf491..c4b853e5f6 100644 --- a/toolkit/data-sources/db-sync/src/block/mod.rs +++ b/toolkit/data-sources/db-sync/src/block/mod.rs @@ -75,7 +75,7 @@ impl BlockDataSourceImpl { let reference_timestamp = BlockDataSourceImpl::timestamp_to_db_type(reference_timestamp)?; let latest = self.get_latest_block_info().await?; let offset = self.security_parameter + self.block_stability_margin; - let stable = BlockNumber(latest.number.0.saturating_sub(offset)); + let stable = latest.number.saturating_sub(offset).into(); let block = self.get_latest_block(stable, reference_timestamp).await?; Ok(block.map(From::from)) } @@ -255,7 +255,7 @@ impl BlockDataSourceImpl { Ok(block .zip(latest_block) .filter(|(block, latest_block)| { - block.block_no.0 + self.security_parameter <= latest_block.block_no.0 + block.block_no.saturating_add(self.security_parameter) <= latest_block.block_no && self.is_block_time_valid(block, reference_timestamp) }) .map(|(block, _)| block)) @@ -274,11 +274,10 @@ impl BlockDataSourceImpl { .ok_or(InternalDataSourceError( "No latest block when filling the caches.".to_string(), ))?; - let latest_block_num = latest_block.block_no.0; - let stable_block_num = latest_block_num.saturating_sub(self.security_parameter); + let stable_block_num = latest_block.block_no.saturating_sub(self.security_parameter); - let to_block_no = BlockNumber(from_block_no.0.saturating_add(size).min(stable_block_num)); - let blocks = if to_block_no.0 > from_block_no.0 { + let to_block_no = from_block_no.saturating_add(size).min(stable_block_num); + let blocks = if to_block_no > from_block_no { db_model::get_blocks_by_numbers(&self.pool, from_block_no, to_block_no).await? } else { vec![from_block.clone()] diff --git a/toolkit/data-sources/db-sync/src/bridge/mod.rs b/toolkit/data-sources/db-sync/src/bridge/mod.rs index b5b108c267..0670144baa 100644 --- a/toolkit/data-sources/db-sync/src/bridge/mod.rs +++ b/toolkit/data-sources/db-sync/src/bridge/mod.rs @@ -116,13 +116,13 @@ fn utxo_to_transfer( where RecipientAddress: for<'a> TryFrom<&'a [u8]>, { - let token_delta = (utxo.tokens_out.0 as i128) - (utxo.tokens_in.0 as i128); + let token_delta = utxo.tokens_out.checked_sub_i128(utxo.tokens_in)?; - if token_delta <= 0 { + if token_delta.is_zero() { return None; } - let token_amount = token_delta as u64; + let token_amount = token_delta.0 as u64; let transfer = match TokenTransferDatum::try_from(utxo.datum.0.clone()) { Ok(TokenTransferDatum::V1(TokenTransferDatumV1::UserTransfer { receiver })) => { diff --git a/toolkit/data-sources/db-sync/src/db_model.rs b/toolkit/data-sources/db-sync/src/db_model.rs index 0f225ebc64..8610693be1 100644 --- a/toolkit/data-sources/db-sync/src/db_model.rs +++ b/toolkit/data-sources/db-sync/src/db_model.rs @@ -189,7 +189,7 @@ pub(crate) struct DatumChangeOutput { pub action: GovernedMapAction, } -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, PartialEq, Copy)] pub(crate) struct NativeTokenAmount(pub u128); impl From for sidechain_domain::NativeTokenAmount { fn from(value: NativeTokenAmount) -> Self { @@ -197,6 +197,16 @@ impl From for sidechain_domain::NativeTokenAmount { } } +impl NativeTokenAmount { + pub(crate) fn checked_sub_i128(self, rhs: NativeTokenAmount) -> Option { + self.0.checked_sub(rhs.0).map(NativeTokenAmount) + } + + pub(crate) fn is_zero(&self) -> bool { + self.0 == 0 + } +} + impl sqlx::Type for NativeTokenAmount { fn type_info() -> ::TypeInfo { PgTypeInfo::with_name("NUMERIC") diff --git a/toolkit/data-sources/db-sync/src/governed_map/mod.rs b/toolkit/data-sources/db-sync/src/governed_map/mod.rs index 193af54aeb..726c82fceb 100644 --- a/toolkit/data-sources/db-sync/src/governed_map/mod.rs +++ b/toolkit/data-sources/db-sync/src/governed_map/mod.rs @@ -216,8 +216,7 @@ impl GovernedMapDataSource for GovernedMapDataSourceCachedImpl { Some(block) => BlockNumber(block.number.0), None => up_to_block_number, }; - let since_block_plus = - BlockNumber(since_block_number.unwrap_or(BlockNumber(0)).0 + self.cache_size as u32); + let since_block_plus = since_block_number.unwrap_or_default().saturating_add(self.cache_size); let max_search_block = min(latest_stable_block, max(up_to_block_number, since_block_plus)); let changes = self @@ -307,8 +306,8 @@ fn filter_changes_in_range( changes .into_iter() .filter(|change| { - change.block_no.0 <= up_to_block.0 - && since_block.map(|b| change.block_no.0 > b.0).unwrap_or(true) + change.block_no <= up_to_block + && since_block.map(|b| change.block_no > b).unwrap_or(true) }) .map(|change| (change.key, change.value)) .collect() @@ -327,8 +326,8 @@ impl Cache { return None; }; - if highest_block_number.0 < up_to_block.0 - || since_block.map(|b| b.0 < lowest_block_number.0).unwrap_or(false) + if highest_block_number < up_to_block + || since_block.map(|b| b < lowest_block_number).unwrap_or(false) { return None; } diff --git a/toolkit/sidechain/domain/src/lib.rs b/toolkit/sidechain/domain/src/lib.rs index c09183b709..346e98a4a0 100644 --- a/toolkit/sidechain/domain/src/lib.rs +++ b/toolkit/sidechain/domain/src/lib.rs @@ -162,6 +162,18 @@ impl Display for McBlockNumber { } } +impl McBlockNumber { + /// Adds `rhs` to the block number without overflow + pub fn saturating_add>(self, rhs: Rhs) -> Self { + Self(self.0.saturating_add(rhs.into())) + } + + /// Subtracts `rhs` from the block number without overflow + pub fn saturating_sub>(self, rhs: Rhs) -> Self { + Self(self.0.saturating_sub(rhs.into())) + } +} + #[derive( Default, Debug, @@ -199,6 +211,8 @@ impl Display for McSlotNumber { TypeInfo, Hash, MaxEncodedLen, + PartialOrd, + Ord, )] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize, FromStr))] /// Partner Chain slot number @@ -1458,7 +1472,7 @@ impl alloc::fmt::Debug for DelegatorKey { } /// Amount of Lovelace staked by a Cardano delegator to a single stake pool -#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd)] +#[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd)] pub struct DelegatorStakeAmount(pub u64); impl> From for DelegatorStakeAmount { diff --git a/toolkit/sidechain/sidechain-block-search/src/impl_compare_strategy.rs b/toolkit/sidechain/sidechain-block-search/src/impl_compare_strategy.rs index 7dd6c8c690..b8f5cda527 100644 --- a/toolkit/sidechain/sidechain-block-search/src/impl_compare_strategy.rs +++ b/toolkit/sidechain/sidechain-block-search/src/impl_compare_strategy.rs @@ -58,9 +58,9 @@ where block_info: &BlockInfo, ) -> Result { let slot_of_block = block_info.get_slot_of_block(block)?; - let ordering = if slot_of_block.0 < self.slot_range.start.0 { + let ordering = if slot_of_block < self.slot_range.start { Ordering::Less - } else if slot_of_block.0 >= self.slot_range.end.0 { + } else if slot_of_block >= self.slot_range.end { Ordering::Greater } else { Ordering::Equal diff --git a/toolkit/smart-contracts/offchain/tests/integration_tests.rs b/toolkit/smart-contracts/offchain/tests/integration_tests.rs index 2d0776ae05..5f9a2664e5 100644 --- a/toolkit/smart-contracts/offchain/tests/integration_tests.rs +++ b/toolkit/smart-contracts/offchain/tests/integration_tests.rs @@ -407,7 +407,7 @@ async fn governance_action_can_be_initiated_by_non_governance() { run_assemble_and_sign(tx_to_sign, &[GOVERNANCE_AUTHORITY_KEY], &client).await; } -async fn initialize<'a>(container: &ContainerAsync) -> OgmiosClients { +async fn initialize(container: &ContainerAsync) -> OgmiosClients { let ogmios_port = container.get_host_port_ipv4(1337).await.unwrap(); println!("Ogmios port: {}", ogmios_port); diff --git a/toolkit/utils/db-sync-sqlx/src/lib.rs b/toolkit/utils/db-sync-sqlx/src/lib.rs index 1cc2cfcf4d..41f3dd881a 100644 --- a/toolkit/utils/db-sync-sqlx/src/lib.rs +++ b/toolkit/utils/db-sync-sqlx/src/lib.rs @@ -82,10 +82,20 @@ macro_rules! sqlx_implementations_for_wrapper { } /// Cardano block number -#[derive(Debug, Copy, Ord, PartialOrd, Clone, PartialEq, Eq)] +#[derive(Debug, Copy, Ord, PartialOrd, Clone, PartialEq, Eq, Default)] pub struct BlockNumber(pub u32); sqlx_implementations_for_wrapper!(i32, "INT4", BlockNumber, McBlockNumber); +impl BlockNumber { + pub fn saturating_add>(self, rhs: Rhs) -> Self { + Self(self.0.saturating_add(rhs.into())) + } + + pub fn saturating_sub>(self, rhs: Rhs) -> Self { + Self(self.0.saturating_sub(rhs.into())) + } +} + /// Cardano epoch number #[derive(Debug, Copy, Clone, PartialEq)] pub struct EpochNumber(pub u32);